package com.flashflexpro.flexdirector.agent.scriptrunner {
import com.flashflexpro.flexdirector.agent.console.Console;
import com.flashflexpro.flexdirector.constant.DirectorMetadata;

import flash.events.EventDispatcher;
import flash.utils.describeType;

    import flash.utils.getQualifiedClassName;

    import mx.collections.Sort;
import mx.collections.XMLListCollection;

//abstract
public class RunningProcedure extends EventDispatcher {

    public function RunningProcedure(procedure:IUsingScriptRunner) {
        ScriptRunner.procedure2runner[ procedure ] = this;
        ScriptRunner.currentProcedure = procedure;
        _procedure = procedure;
        var xdesc:XML = describeType(_procedure);
        _procedureClassName = xdesc.@name;
        _procedureClassName = _procedureClassName.split("::")[ 1 ];
        _procedureMethods = new XMLListCollection(xdesc.method.(metadata.@name==DirectorMetadata.metaName));
        var sort:Sort = new Sort();
        sort.compareFunction = function( a:XML, b:XML, fields:*=null):int{
            var name1:String = a.@name;
            var name2:String = b.@name;
            var s1:int = int( name1.split( "_" )[2] );
            var s2:int = int( name2.split( "_" )[2] );
            if( s1 > s2 ){
                return 1;
            }
            if( s2 > s1 ){
                return -1;
            }
            throw new Error( "sequence number can't be same!" );

        };
        _procedureMethods.sort = sort;
        _procedureMethods.refresh();
        Console.inst.procedureStart( _procedureClassName );
    }

    protected var _index:int = 0;
    public function get index():int {
        return _index;
    }

    protected var _procedure:IUsingScriptRunner;
    private var _procedureClassName:String;
    public function get procedureClassName():String{
        return _procedureClassName;
    }
    private var _procedureMethods:XMLListCollection;

    public function get procedure():IUsingScriptRunner {
        return _procedure;
    }


    private var _currentRunningStep:RunningStep;
    public function get currentRunningStep():RunningStep {
        return _currentRunningStep;
    }

    public function run():void {
        _currentRunningStep = new RunningStep( _procedureMethods.getItemAt( _index ) as XML, this );
        _currentRunningStep.execute();
    }

    internal function onStepComplete( exitOnFailure:Boolean ):void {
        if ( exitOnFailure || _index >= _procedureMethods.length - 1 ) {
            if( exitOnFailure ){
                Console.inst.procedureFailed( _procedureClassName );
            }
            else{
                Console.inst.procedureSuceeded( _procedureClassName );
            }
            delete ScriptRunner.procedure2runner[ _procedure ];
            var r:RunningProcedure = ScriptRunner.procedure2runner[ _procedure.owner ] as RunningProcedure;
            if( r != null ){
                r.onStepComplete( exitOnFailure );
            }
            else{
                trace( "Success!" );
            }
            return;
        }
        _index ++;
        run();
    }


}
}